Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added tests around IO::watch and IO::unwatch #1659

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft

Conversation

DavyLandman
Copy link
Member

Codecov pointed out there were not test for them.

Writing the test I found a bug, so also fixed that.

Note the bug is minor, it would sometimes share too many events.

@codecov
Copy link

codecov bot commented Sep 29, 2022

Codecov Report

Merging #1659 (30d24a7) into main (2cdd87a) will increase coverage by 0%.
The diff coverage is 58%.

@@           Coverage Diff            @@
##              main   #1659    +/-   ##
========================================
  Coverage       48%     48%            
- Complexity    5982    6050    +68     
========================================
  Files          669     669            
  Lines        58308   58320    +12     
  Branches      8497    8501     +4     
========================================
+ Hits         28409   28559   +150     
+ Misses       27763   27597   -166     
- Partials      2136    2164    +28     
Impacted Files Coverage Δ
src/org/rascalmpl/library/Prelude.java 44% <50%> (+1%) ⬆️
...calmpl/test/infrastructure/RecursiveTestSuite.java 81% <100%> (+1%) ⬆️
...almpl/interpreter/result/ListOrRelationResult.java 62% <0%> (-6%) ⬇️
...g/rascalmpl/parser/gtd/location/PositionStore.java 65% <0%> (-5%) ⬇️
...c/org/rascalmpl/interpreter/result/NodeResult.java 68% <0%> (-1%) ⬇️
...ary/lang/json/internal/JSONReadingTypeVisitor.java 72% <0%> (-1%) ⬇️
src/org/rascalmpl/uri/URIUtil.java 37% <0%> (-1%) ⬇️
src/org/rascalmpl/interpreter/result/Result.java 13% <0%> (-1%) ⬇️
...g/rascalmpl/interpreter/result/RationalResult.java 32% <0%> (ø)
src/org/rascalmpl/interpreter/Evaluator.java 26% <0%> (+<1%) ⬆️
... and 19 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@DavyLandman
Copy link
Member Author

Hmm, something is going wrong with calculating the test coverage (or running tests) as this commit should have increased the test coverage in prelude. not decrease it.

@DavyLandman
Copy link
Member Author

image
I know this code is hit by the test, so something is going wrong with the merging of test coverages.

@jurgenvinju
Copy link
Member

We do have time for other people's bugs.

@jurgenvinju
Copy link
Member

Is it possible that our handwritten (parallel) "JUnit" test runners are messing up what is going on here? At least their Descriptions are all wrong and not pointing to the source module anymore for a few years already.

@DavyLandman
Copy link
Member Author

DavyLandman commented Sep 30, 2022

Ok, solved it, the RecursiveTestSuite runner was not detecting plain junit classes. So this IOTest was just never triggered.

@DavyLandman
Copy link
Member Author

ouch, the watches aren't working as expected on OSX :|

@DavyLandman
Copy link
Member Author

Still breaking in Mac OSX. It seems it's an actual bug.

@jurgenvinju
Copy link
Member

Good progress. Can we write this test also in Rascal and would it not be simpler? I'm curious about the Mac bug as well.

@jurgenvinju
Copy link
Member

What happens with a bigger wait time on Mac?

@DavyLandman
Copy link
Member Author

Can we write this test also in Rascal and would it not be simpler?

We need to sleep outside of the rascal evaluator lock, so the watch thread can get the lock on the evaluator to invoke the callback. So that's why we cannot do this in pure rascal.

What happens with a bigger wait time on Mac?

Could you give that a try on your machine? Maybe indeed the interval that the Mac api triggers is slower than on linux or windows. But finding this out via multiple commits seems a bit wasteful.

@jurgenvinju jurgenvinju marked this pull request as draft April 22, 2023 07:14
@jurgenvinju jurgenvinju self-requested a review April 22, 2023 07:14
@jurgenvinju jurgenvinju self-assigned this Apr 22, 2023
@jurgenvinju
Copy link
Member

I experimented with the tests and it seems in this case the watchers do work correctly, also on Mac, but the tests are unreliable under certain circumstances. The problem is that the Mac implementation of the watchers is built internally with a polling mechanism that uses timestamps, which behaves differently and can violate the assumption under which these tests have been written.

  • One difference in semantics is that the poller may report file changes that are older, from before the watcher was even registered, to the current watcher.

Another related issue is that tests do have impact on each other via:

  1. the file system
  2. the registry of watchers

This, in combination with the above difference in semantics, can also lead to the current test suite failing for no other reason than the way they were designed.

We could figure out a different way of testing the watchers:

  • should not abstract from the location scheme. We should test with file as well as others to get coverage of the different implementations.
  • should use clean and unique tmp folders for every test.
  • allow for additional changes to be reported by a watcher next to the expected change
  • test for specific changes with specific locations rather than counting them

@DavyLandman
Copy link
Member Author

I experimented with the tests and it seems in this case the watchers do work correctly, also on Mac, but the tests are unreliable under certain circumstances. The problem is that the Mac implementation of the watchers is built internally with a polling mechanism that uses timestamps, which behaves differently and can violate the assumption under which these tests have been written.

* One difference in semantics is that the poller may report file changes that are older, from before the watcher was even registered, to the current watcher.

Okay, that is indeed bad. There is an api in osx (WatchService) and there do seem to be libraries that support that via a JNI binding: https://github.com/gmethvin/directory-watcher

Another related issue is that tests do have impact on each other via:
1. the file system
2. the registry of watchers

This, in combination with the above difference in semantics, can also lead to the current test suite failing for no other reason than the way they were designed.

Could you elaborate a bit more? Are you talking about the time between a watch setup and the file events that happen closely thereafter?

We could figure out a different way of testing the watchers:
* should not abstract from the location scheme. We should test with file as well as others to get coverage of the different implementations.
* should use clean and unique tmp folders for every test.
* allow for additional changes to be reported by a watcher next to the expected change
* test for specific changes with specific locations rather than counting them

Agreed, but my first goal was to get any testing in there, just so that we're not missing breaking changes when we introduce them.

Copy link
Member

@jurgenvinju jurgenvinju left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good tests!

I'd rather add a sleep function to util::Benchmark or util::Reflective for testing purposes, and rewrite the tests in Rascal test functions, than introduce yet another place for making and configuring and testing our own evaluators. These tests will not survive the move to the compiler otherwise, while we are testing functionality that is 100% independent of the compiler/interpreter divide.

@jurgenvinju
Copy link
Member

According to the docs we have no sleep yet anywhere.

@DavyLandman
Copy link
Member Author

We've also been working on https://github.com/SWAT-engineering/java-watch which would be the library that can be used for this feature. as of right now it at least handles recursive watches correctly, but it still has the OSX polling problem.

We're aware of a solution strategy, but have to allocate time for it.

The library does have quite a nice test suite, and what we've learned is that you'll always have to include some sleeps/waits for stuff to stabilize, as you have no real guarantees how quickly events will be reported. In the end we have almost no sleeps in the test, but more a condition to wait for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants